/*
 * File: SubversionContext.java
 * Author: Force Charlie
 * CreateTime: @2015.10
 * Copyright (C) 2018 GITEE.COM. All Rights Reserved.
 */

package svnserver.service;

import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import org.tmatesoft.svn.core.SVNException;
import svnserver.auth.User;
import svnserver.parser.SvnServerParser;
import svnserver.parser.SvnServerWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class SubversionContext {
  private static final org.slf4j.Logger log = LoggerFactory.getLogger(SubversionContext.class);

  public User getUser() {
    return user;
  }

  private User user;

  public AuthorizeResult AuthResult() {
    return authResult;
  }

  private static int ParseUID(@NotNull String token) {
    int index = token.indexOf('$');
    if (index == -1) {
      return -1;
    }
    String s = token.substring(0, index);
    String[] va = s.split(";");
    if (va == null) {
      return -1;
    }
    String suid = "-1";
    String sshtoken = "";
    for (int i = 0; i < va.length; i++) {
      String[] k = va[i].split("=");
      if (k == null || k.length < 2) {
        continue;
      }
      if (k[0].equals("userid")) {
        suid = k[1];
        continue;
      }
      if (k[0].equals("uid")) {
        suid = k[1];
        continue;
      }
      if (k[0].equals("token")) {
        sshtoken = k[1];
      }
    }
    if (Parameters.Get().SshNeedToken() && !Parameters.Get().SshToken().equals(sshtoken)) {
      log.error("bad token: {}", sshtoken);
      return -1;
    }
    try {
      return Integer.parseInt(suid);
    } catch (Exception ignore) {
      return -1;
    }
  }

  private AuthorizeResult authResult;

  public static SubversionContext Create(@NotNull SvnServerParser parser, @NotNull SvnServerWriter writer,
      @NotNull String token, @NotNull SubversionPath spi, boolean isssh) throws IOException, SVNException {

    SubversionContext context = new SubversionContext();
    if (isssh) {
      if (token == null) {
        return null;
      }
      int userid = ParseUID(token);
      if (userid < 0) {
        return null;
      }

      context.authResult = AuthorizeManager.SubversionAuthorizeEx(null, null, userid, spi);
      if (context.authResult.ErrorCode() == 0) {
        context.user = context.authResult.MakeUser();
      }
    } else {
      final String decodedToken = new String(Base64.getDecoder().decode(token.trim()), StandardCharsets.US_ASCII);
      final String[] credentials = decodedToken.split("\u0000");
      if (credentials.length < 3)
        return null;

      final String username = credentials[1];
      final String password = credentials[2];

      //// when input space or tab
      if (password.trim().isEmpty() || username.trim().isEmpty()) {
        return null;
      }
      context.authResult = AuthorizeManager.SubversionAuthorizeEx(username, password, -1, spi);
      if (context.authResult.ErrorCode() == 0) {
        context.user = context.authResult.MakeUser();
      }
    }
    return context;
  }
}
